/*
 * Copyright (c) 2022 Kirky
 * Licensed under the Open Software Licence, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/osl-3.0.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lingeringdream.luciole.helper.identity;

/**
 * @author Kirky
 * @version 1.0
 * @date 2022/4/30
 */
public class IdentityHelper2 {
    /*private final Context context;
    private final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x0023, IdentityHelper.class.getSimpleName());
    private Model model;
    private LiteSession session;

    public IdentityHelper(Context context1) {
        context = context1;
    }

    *//**
     * 加载模型
     *
     * @param modelName
     * @return 是否加载成功
     *//*
    private boolean loadModel(String modelName) {
        MSContext msContext = new MSContext();
        msContext.init(2, CpuBindMode.MID_CPU);
        msContext.addDeviceInfo(DeviceType.DT_CPU, true);

        FileInputStream fileInputStream = null;
        RawFileDescriptor rawFileDescriptor = null;
        boolean isReturnSuccess;

        model = new Model();

        try {
//            加载模型文件
            rawFileDescriptor = context.getResourceManager().getRawFileEntry(modelName).openRawFileDescriptor();
            fileInputStream = new FileInputStream(rawFileDescriptor.getFileDescriptor());
            FileChannel fileChannel = fileInputStream.getChannel();
            long startOffset = rawFileDescriptor.getStartPosition();
            long declaredLen = rawFileDescriptor.getFileSize();
            MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLen);
            isReturnSuccess = model.loadModel(modelName);//(buffer, ModelType.MT_MINDIR, msContext);
//            Method method = model.getClass().getDeclaredMethod("loadModel", MappedByteBuffer.class);
//            method.setAccessible(true);
//            isReturnSuccess = (long) method.invoke(model,buffer) == 0;
            HiLog.info(TAG, "[MS_LITE]\tLoad model results：" + isReturnSuccess);
//            创建配置上下文MSConfig，保存会话所需的一些基本配置参数，用于指导图编译和图执行。
            MSConfig msConfig = new MSConfig();
            if (!msConfig.init(DeviceType.DT_CPU, 2, CpuBindMode.MID_CPU, true)) {
                HiLog.info(TAG, "[MS_LITE]\tThis demo inits context unsuccessfully！");
                return false;
            }
//            创建LiteSession，并调用init方法将上一步得到MSConfig配置到会话中
            session = new LiteSession();
            if (!session.init(msConfig)) {
                HiLog.info(TAG, "[MS_LITE]\tThis demo creates session unsuccessfully");
                msConfig.free();
                return false;
            }
            msConfig.free();
//            调用LiteSession的compileGraph接口进行图编译，主要进行子图切分、算子选型调度
            if (!session.compileGraph(model)) {
                HiLog.info(TAG, "[MS_LITE]\tThis demo compiles graph unsuccessfully");
                model.freeBuffer();
                return false;
            }
            model.freeBuffer();

        } catch (IOException e) {
            HiLog.error(TAG, "[MS_LITE]\tLoad model failed！");
            isReturnSuccess = false;
//        } catch (NoSuchMethodException e1) {
//            HiLog.error(TAG, "[MS_LITE]\tNo catch method！");
//            isReturnSuccess = false;
//        } catch (IllegalAccessException | InvocationTargetException exception){
//            HiLog.error(TAG, "[MS_LITE]\tIllegalAccess,InvocationTarget！");
//            isReturnSuccess = false;
        }
        finally{
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    HiLog.error(TAG, "[MS_LITE]Close file failed");
                    isReturnSuccess = false;
                }
            }

            if (rawFileDescriptor != null) {
                try {
                    rawFileDescriptor.close();
                } catch (IOException e) {
                    HiLog.error(TAG, "[MS_LITE]Close fileDescriptor failed");
                    isReturnSuccess = false;
                }
            }
        }

        return isReturnSuccess;
    }

    *//**
     * 将Image数据修正为ByteBuffer
     *//*
    private ByteBuffer correctionData(Image image) {
        if (image == null) {
            HiLog.error(TAG, "image data is null!");
            return null;
        }
        int height = 224;//image.getImageSize().height/10;
        int width = 224;//image.getImageSize().width/10;
//        将Image转为PixelMap
        Image.Component component = image.getComponent(ImageFormat.ComponentType.JPEG);
        byte[] bytes = new byte[component.remaining()];
        component.read(bytes);
        ImageSource.SourceOptions options = new ImageSource.SourceOptions();
        options.formatHint = "image/jpeg";
        ImageSource imageSource = ImageSource.create(bytes, options);
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.desiredSize = new Size(width, height);
        PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);

        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(width * height * 4 * 3);

//        修正数据
        final float[] IMAGE_MEAN = new float[]{0.485f * 255f, 0.456f * 255f, 0.406f * 255f};
        final float[] IMAGE_STD = new float[]{0.229f * 255f, 0.224f * 255f, 0.225f * 255f};

        int index = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                Position position = new Position(j, i);
                int aRGB = pixelMap.readPixel(position);
                RgbColor color = RgbColor.fromArgbInt(aRGB);
                byteBuffer.putFloat(index, (color.getRed() - IMAGE_MEAN[0]) / IMAGE_STD[0]);
                byteBuffer.putFloat(index + 4, (color.getGreen() - IMAGE_MEAN[1]) / IMAGE_STD[1]);
                byteBuffer.putFloat(index + 8, (color.getBlue() - IMAGE_MEAN[2]) / IMAGE_STD[2]);
                index += 4 * 3;
            }
        }
        HiLog.info(TAG, "bytebuffer>>>" + byteBuffer);
        return byteBuffer;
    }

    public String byImageReceiver(@NonNull ImageReceiver imageReceiver) {
        if (model == null) {
            loadModel("entry/resources/rawfile/mindspore.ms");
        }
        if (model == null) {
            HiLog.error(TAG, "model is null!");
            return null;
        }
        // Set Input Data.
        Image image = imageReceiver.readNextImage();
        ByteBuffer byteBuffer = correctionData(image);
        if (model != null) {
            List<MSTensor> inputs = session.getInputs();
          *//*  int[][] dims = {{1, image.getImageSize().width/10, image.getImageSize().height/10, 3}};
            if (model.resize(inputs, dims)) {*//*
            MSTensor inputTensor = inputs.get(0);
            if (inputTensor.setData(byteBuffer)) {
                if (session.runGraph()) {
                    List<String> tensorNames = session.getOutputTensorNames();
                    Map<String, MSTensor> outputs = session.getOutputMapByTensor();
                    Set<Map.Entry<String, MSTensor>> entries = outputs.entrySet();
                    for (String tensorName : tensorNames) {
                        MSTensor output = outputs.get(tensorName);
                        if (output == null) {
                            HiLog.error(TAG, "MS_LITE\tCan not find output " + tensorName);
                            return null;
                        }
                        float[] results = output.getFloatData();

                        StringBuilder msgSb = new StringBuilder();
                        for (float f : results) {
                            msgSb.append(" ").append(f);
                        }
                        HiLog.info(TAG, "MS_LITE\t" + tensorName + ": " + msgSb);
                    }

                       *//* List<MSTensor> outTensors = model.getOutputs();
                        MSTensor outputTensor = outTensors.get(0);
                        HiLog.info(TAG, "output size >>>"+outTensors.size());
                        float[] output = outputTensor.getFloatData();
                        HiLog.info(TAG, "output size >>>"+output.length);
//                        Set set = new HashSet();
//                        for(float f:output) {
//                            HiLog.info(TAG, "output item >>>"+f);
//                            set.add(f);
//                        }
//                        HiLog.info(TAG, "output >>>"+ set);*//*
                } else {
                    HiLog.info(TAG, "runGraph失败！");
                }
            } else {
                HiLog.info(TAG, "setData失败！");
            }
           *//* } else {
                HiLog.info(TAG, "resize失败！");
            }*//*
        }
        return null;
    }

    *//**
     * 释放模型
     *//*
    public void release() {
        if (model != null) {
            model.free();
            model = null;
        }
    }

    private boolean printTensorData(MSTensor outTensor) {
        int[] shape = outTensor.getShape();
        StringBuilder msgSb = new StringBuilder();
        msgSb.append("out tensor shape: [");
        for (int dim : shape) {
            msgSb.append(dim).append(",");
        }
        msgSb.append("]");
        if (outTensor.getDataType() != DataType.kNumberTypeFloat32) {
            HiLog.error(TAG, "output tensor data type is not float, the data type is " + outTensor.getDataType());
            return false;
        }
        float[] result = outTensor.getFloatData();
        if (result == null) {
            HiLog.error(TAG, "decodeBytes return null");
            return false;
        }
        msgSb.append(" and out data:");
        for (int i = 0; i < outTensor.elementsNum(); i++) {
            msgSb.append(" ").append(result[i]);
        }
        HiLog.info(TAG, msgSb.toString());
        return true;
    }*/
}
